"""Prime number generator

Produces a generator object that iterates until a maximum value is reached.

Includes three functions, primes(max), primes_gen(max) and primes_gen2(max).

primes(max) returns a list of primes below an integer max.

primes_gen(max) and primes_gen2(max) iterate through primes below max using
generator functions.  primes_gen2(max) is slower and therefore deprecated, but
is less processor intensive.
"""

__author__  = "Avinash Vora"
__version__ = "v 1.5"

def primes(max):
	"""Returns a list of primes"""
	primes = [2]
	is_prime = True
	x = 3
	y = 0
	
	while x < max:
		if x % 2:
			while y <= len(primes) - 1:
				if x % primes[y]:
					y += 1
				else:
					is_prime = False
					break
			if is_prime:
				primes.append(x)
		is_prime = True
		x += 1
		y = 0
	return primes

def primes_gen(max):
	"""Generates primes using generators"""
	primes = [2]
	is_prime = True
	x = 2
	y = 0
	
	yield x
	
	while x < max:
		if x % 2:
			while y <= len(primes) - 1:
				if x % primes[y]:
					y += 1
				else:
					is_prime = False
					break
			if is_prime:
				primes.append(x)
				yield x
		is_prime = True
		x += 1
		y = 0

def primes_gen2(max):
	"""Generates primes using generators (deprecated)"""
	is_prime = True
	x = 2
	y = 3
	
	yield x
	
	while x < max:
		if x % 2:
			while y <= ((x / 2) - 1):
				if x % y:
					y += 1
				else:
					is_prime = False
					break
			if is_prime:
				yield x
		is_prime = True
		x += 1
		y = 3

def cardinal(num):
	"""Returns a string giving the cardinal number, eg. "1st"."""
	if isinstance(num, int):
		num = str(num)
	
	if num[-1] == "1":
		return num + "st"
	elif num[-1] == "2":
		return num + "nd"
	elif num[-1] == "3":
		return num + "rd"
	else:
		return num + "th"

def usage():
	print "Usage: primes.py [-n(nth prime)] max"
	sys.exit(2)

if __name__ == "__main__":
	import sys, getopt

	try:
		opts, args = getopt.getopt(sys.argv[1:], "n:")
	except getopt.GetoptError:
		usage()
	if not args:
		usage()
	
	try:
		result = primes(int(args[0]))
	except:
		usage()
	
	for n in result:
		print n,
	
	print "\n"
	
	for o, a in opts:
		if o == "-n":
			if int(a) <= len(result) - 1:
				print "The " + cardinal(a) + " prime is " + str(result[int(a) - 1]) + "."
			else:
				print a + " is out of range.  Select a higher maximum value."
		else:
			usage()